package chat.network;

import java.io.IOException;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import chat.protocol.Protocol;

/**
 * A client thats using sockets 
 * to speak to a server.
 * 
 * Provides ways to:
 * connect
 * disconnect
 * send
 * receive
 * 
 * @author Johan
 *
 */
public class SocketClient {
	private Protocol protocol;
	private Socket socket;
	private SocketListner listner;
	private PrintWriter write;
	
	/**
	 * Connects to a given server.
	 * @param ip - ip number/host name
	 * @param port - The port number the server i running on.
	 * @throws UnknownHostException - If it doesn't find the server.
	 * @throws IOException - If it fails to read from server.
	 */
	public void connect(String ip, int port) throws UnknownHostException, IOException{
		_connect(ip, port);
	}
	private void _connect(String ip, int port) throws UnknownHostException, IOException{
		socket = new Socket(ip, port);
		write = new PrintWriter(socket.getOutputStream(), true);
		addListner(socket);
	}
	private void addListner(Socket s) throws IOException{
		listner = new SocketListner(s, this);
	}
	/**
	 * Disconnect from connected server.
	 * Needs to be connected to a server to disconnect,
	 * else nothing happens.
	 * @throws IOException
	 */
	public void disconnect() throws IOException{
		_disconnect();
	}
	private void _disconnect() throws IOException {
		if(socket != null){
			listner.destroy();
			write.close();
			socket.close();
			listner = null;
		}
	}
	
	/**
	 * Send a message over a socket.
	 * @param message - The message to be sent
	 */
	public void send(String message){
		_send(message);
	}
	private void _send(String message) {
		write.println(message);
	}
	/**
	 * Gets active when a response from the server arrives.
	 * @param message - Response
	 */
	public void receive(String message){
		if(protocol == null){
			System.out.println(message);
		} else {
			protocol.processInput(message);
		}
	}
	
	/**
	 * Connects the client whit the protocol.
	 * Really important to remember!
	 * @param p - Protocol to be connected to this SocketClient.
	 */
	public void addProtocol(Protocol p){
		protocol = p;
	}

}
